home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / show / jpgagasr.lha / ppm2aga / ppmlib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-15  |  14.5 KB  |  601 lines

  1. /* pbm utility library
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. /* modified by Günther Röhrich */
  14. /* WARNING: This file is not for use with normal pbm programs */
  15.  
  16. /* support functions for the ppm stuff */
  17.  
  18. #include <stdarg.h>
  19. #include "ppm.h"
  20. #include "ppm2AGA.h"
  21. #include "libpbm.h"
  22. #include "libppm.h"
  23. #include "libpgm.h"
  24.  
  25. extern jmp_buf ErrorEnv;
  26. static bit pbm_getbit(FILE *);
  27. extern pixel **pixels;
  28. extern int cols;
  29. extern int rows;
  30. extern int rowcnt;
  31. extern pixel *pixrow;
  32. extern pixval maxval;
  33. extern int ppmformat;
  34. extern int ColorRegMax;
  35.  
  36. extern long  *thisrerr;
  37. extern long  *nextrerr;
  38. extern long  *thisgerr;
  39. extern long  *nextgerr;
  40. extern long  *thisberr; 
  41. extern long  *nextberr;     
  42. extern int Convert4096; 
  43. extern int fs_direction;
  44. #define FS_SCALE 1024
  45.  
  46. void FSrow(pixel *pixelrow, int cols);
  47.  
  48. /* this is called when an error in ppm2ilbm() is found */
  49. void pm_error(char *format, ...)
  50. {
  51.  va_list args;
  52.  va_start(args, format);
  53.  vprintf(format, args); /* modify this if we don't output to stdout any more */
  54.  va_end(args);
  55.  longjmp(ErrorEnv, 10);
  56. }
  57.  
  58. /* this is defined in ppm2AGA.c
  59. void pm_message(char *format, ...)
  60. {
  61.  va_list args;
  62.  va_start(args, format);
  63.  vprintf(format, args); 
  64.  va_end(args);
  65. }
  66. */
  67.  
  68. void ppm_readppminitrest(FILE *file, int *colsP, int *rowsP, pixval *maxvalP)
  69.     {
  70.     int maxval;
  71.  
  72.     /* Read size. */
  73.     *colsP = pbm_getint( file );
  74.     *rowsP = pbm_getint( file );
  75.  
  76.     /* Read maxval. */
  77.     maxval = pbm_getint( file );
  78.     if ( maxval > PPM_MAXMAXVAL )
  79.     pm_error(
  80. "maxval is too large - try reconfiguring with PGM_BIGGRAYS\n\
  81.     or without PPM_PACKCOLORS\n" );
  82.     *maxvalP = maxval;
  83.     }
  84.  
  85. pixval ppm_pbmmaxval = 1;
  86.  
  87. void ppm_readppminit(FILE *file, int *colsP, int *rowsP, 
  88.                      pixval *maxvalP, int *formatP)
  89.     {
  90.     /* Check magic number. */
  91.     *formatP = pbm_readmagicnumber( file );
  92.     switch ( PPM_FORMAT_TYPE(*formatP) )
  93.     {
  94.     case PPM_TYPE:
  95.     ppm_readppminitrest( file, colsP, rowsP, maxvalP );
  96.     break;
  97.  
  98.     case PGM_TYPE:
  99.     pgm_readpgminitrest( file, colsP, rowsP, maxvalP );
  100.     break;
  101.  
  102.     case PBM_TYPE:
  103.     pbm_readpbminitrest( file, colsP, rowsP );
  104.     *maxvalP = ppm_pbmmaxval;
  105.     break;
  106.  
  107.     default:
  108.     pm_error( "bad magic number - not a ppm, pgm, or pbm file\n" );
  109.     }
  110.     }
  111.  
  112.  
  113. char pbm_getc(FILE *file)
  114.     {
  115.     register int ich;
  116.     register char ch;
  117.  
  118.     ich = getc( file );
  119.     if ( ich == EOF )
  120.     pm_error( "EOF / read error\n" );
  121.     ch = (char) ich;
  122.     
  123.     if ( ch == '#' )
  124.     {
  125.     do
  126.         {
  127.         ich = getc( file );
  128.         if ( ich == EOF )
  129.         pm_error( "EOF / read error\n" );
  130.         ch = (char) ich;
  131.         }
  132.     while ( ch != '\n' && ch != '\r' );
  133.     }
  134.  
  135.     return ch;
  136.     }
  137.  
  138. unsigned char pbm_getrawbyte(FILE *file)
  139.     {
  140.     register int iby;
  141.  
  142.     iby = getc( file );
  143.     if ( iby == EOF )
  144.     pm_error( "EOF / read error\n" );
  145.     return (unsigned char) iby;
  146.     }
  147.  
  148. int pbm_getint(FILE *file)
  149.     {
  150.     register char ch;
  151.     register int i;
  152.  
  153.     do
  154.     {
  155.     ch = pbm_getc( file );
  156.     }
  157.     while ( ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' );
  158.  
  159.     if ( ch < '0' || ch > '9' )
  160.     pm_error( "junk in file where an integer should be\n" );
  161.  
  162.     i = 0;
  163.     do
  164.     {
  165.     i = i * 10 + ch - '0';
  166.     ch = pbm_getc( file );
  167.         }
  168.     while ( ch >= '0' && ch <= '9' );
  169.  
  170.     return i;
  171.     }
  172.  
  173. int pbm_readmagicnumber(FILE *file)
  174.     {
  175.     int ich1, ich2;
  176.  
  177.     ich1 = getc( file );
  178.     if ( ich1 == EOF )
  179.     pm_error( "EOF / read error reading magic number\n" );
  180.     ich2 = getc( file );
  181.     if ( ich2 == EOF )
  182.     pm_error( "EOF / read error reading magic number\n" );
  183.     return ich1 * 256 + ich2;
  184.     }
  185.  
  186.  
  187. void pbm_readpbminitrest(FILE *file, int *colsP, int *rowsP ) 
  188.     {
  189.     /* Read size. */
  190.     *colsP = pbm_getint( file );
  191.     *rowsP = pbm_getint( file );
  192.     }
  193.  
  194. void pgm_readpgminitrest(FILE *file, int *colsP, int *rowsP, gray *maxvalP)
  195.     {
  196.     int maxval;
  197.  
  198.     /* Read size. */
  199.     *colsP = pbm_getint( file );
  200.     *rowsP = pbm_getint( file );
  201.  
  202.     /* Read maxval. */
  203.     maxval = pbm_getint( file );
  204.     if ( maxval > PGM_MAXMAXVAL )
  205.     pm_error( "maxval is too large - try reconfiguring with PGM_BIGGRAYS\n" );
  206.     *maxvalP = maxval;
  207.     }
  208.  
  209. /* Variable-sized arrays. */
  210.  
  211. char*
  212. pm_allocrow( cols, size )
  213.     int cols;
  214.     int size;
  215.     {
  216.     register char* itrow;
  217.  
  218.     itrow = (char*) malloc( cols * size );
  219.     if ( itrow == (char*) 0 )
  220.         pm_error( "out of memory allocating a row\n" );
  221.     return itrow;
  222.     }
  223.  
  224. void
  225. pm_freerow( itrow )
  226.     char* itrow;
  227.     {
  228.     free( itrow );
  229.     }
  230.  
  231. char**
  232. pm_allocarray( cols, rows, size )
  233.     int cols, rows;
  234.     int size;
  235.     {
  236.     char** its;
  237.     int i;
  238.     its = (char**) malloc( (rows + 1) * sizeof(char*) );
  239.     if ( its == (char**) 0 )
  240.         pm_error( "out of memory allocating an array\n" );
  241.  
  242.     /* initialize the array, modified by Günther Röhrich         */
  243.     /* this is needed for using pm_freearray() even if the array */
  244.     /* is not completely allocated                               */
  245.  
  246.     memset((void *)its, 0, (rows + 1) * sizeof(char*));
  247.  
  248.     its[rows] = its[0] = (char*) malloc( rows * cols * size );
  249.     if ( its[0] != (char*) 0 )
  250.         for ( i = 1; i < rows; ++i )
  251.             its[i] = &(its[0][i * cols * size]);
  252.     else
  253.         for( i = 0; i < rows; ++i )
  254.         {
  255.            /* modified by Günther Röhrich */
  256.            if(!(its[i] = (char*) malloc( cols * size )))
  257.            {
  258.              pm_freearray(its, rows);
  259.              its = NULL;
  260.              break;
  261.             }
  262.          }
  263.     return its;
  264.     }
  265.  
  266. void
  267. pm_freearray( its, rows )
  268.     char** its;
  269.     int rows;
  270.     {
  271.     int i;
  272.     if( its[rows] != (char*) 0 )
  273.         free( its[rows] );
  274.     else
  275.         for( i = 0; i < rows; ++i )
  276.             pm_freerow( its[i] );
  277.     free( its );
  278.     }
  279.  
  280. void ppm_readppmrow(FILE* file, pixel* pixelrow, int cols, pixval maxval, int format)
  281.     {
  282.     register int col;
  283.     register pixel* pP;
  284.     register pixval r, g, b;
  285.     gray* grayrow;
  286.     register gray* gP;
  287.     bit* bitrow;
  288.     register bit* bP;
  289.  
  290.     switch ( format )
  291.     {
  292.     case PPM_FORMAT:
  293.       
  294.             for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP )
  295.         {
  296.         r = pbm_getint( file );
  297. #ifdef DEBUG
  298.         if ( r > maxval )
  299.         pm_error( "r value out of bounds (%u > %u)\n", r, maxval );
  300. #endif /*DEBUG*/
  301.         g = pbm_getint( file );
  302. #ifdef DEBUG
  303.         if ( g > maxval )
  304.         pm_error( "g value out of bounds (%u > %u)\n", g, maxval );
  305. #endif /*DEBUG*/
  306.         b = pbm_getint( file );
  307. #ifdef DEBUG
  308.         if ( b > maxval )
  309.         pm_error( "b value out of bounds (%u > %u)\n", b, maxval );
  310. #endif /*DEBUG*/
  311.         PPM_ASSIGN( *pP, r, g, b );
  312.         }  
  313.          if(Convert4096) FSrow(pixelrow, cols);    
  314.          break;    
  315.  
  316.     case RPPM_FORMAT:
  317.     for ( col = 0, pP = pixelrow; col < cols; ++col, ++pP )
  318.         {
  319.         r = pbm_getrawbyte( file );
  320. #ifdef DEBUG
  321.         if ( r > maxval )
  322.         pm_error( "r value out of bounds (%u > %u)\n", r, maxval );
  323. #endif /*DEBUG*/
  324.         g = pbm_getrawbyte( file );
  325. #ifdef DEBUG
  326.         if ( g > maxval )
  327.         pm_error( "g value out of bounds (%u > %u)\n", g, maxval );
  328. #endif /*DEBUG*/
  329.         b = pbm_getrawbyte( file );
  330. #ifdef DEBUG
  331.         if ( b > maxval )
  332.         pm_error( "b value out of bounds (%u > %u)\n", b, maxval );
  333. #endif /*DEBUG*/
  334.         PPM_ASSIGN( *pP, r, g, b );
  335.         }
  336.         if(Convert4096) FSrow(pixelrow, cols);
  337.     break;
  338.  
  339.     case PGM_FORMAT:
  340.     case RPGM_FORMAT:
  341.     grayrow = pgm_allocrow( cols );
  342.     pgm_readpgmrow( file, grayrow, cols, maxval, format );
  343.     for ( col = 0, gP = grayrow, pP = pixelrow; col < cols; ++col, ++gP, ++pP )
  344.         {
  345.         r = *gP;
  346.         PPM_ASSIGN( *pP, r, r, r );
  347.         }
  348.     pgm_freerow( grayrow );
  349.     break;
  350.  
  351.     case PBM_FORMAT:
  352.     case RPBM_FORMAT:
  353.     bitrow = pbm_allocrow( cols );
  354.     pbm_readpbmrow( file, bitrow, cols, format );
  355.     for ( col = 0, bP = bitrow, pP = pixelrow; col < cols; ++col, ++bP, ++pP )
  356.         {
  357.         r = ( *bP == PBM_WHITE ) ? maxval : 0;
  358.         PPM_ASSIGN( *pP, r, r, r );
  359.         }
  360.     pbm_freerow( bitrow );
  361.     break;
  362.  
  363.     default:
  364.     pm_error( "can't happen\n" );
  365.     }
  366.     }
  367.  
  368.  
  369. /* converts one row from 16M colors to 4096 colors using FS dithering */
  370.  
  371. void FSrow(pixel *pixelrow, int cols)
  372.          {
  373.  
  374.            /* if floyd is nonzero we will use Floyd-Steinberg dithering */
  375.            register int col, limitcol;
  376.            register long sg, sr, sb, err;
  377.            long *temperr;
  378.            register pixel *pP;
  379.              
  380.            for ( col = 0; col < cols + 2; ++col )
  381.              nextrerr[col] = nextgerr[col] = nextberr[col] = 0;
  382.  
  383.            if ( fs_direction )
  384.            {
  385.              col = 0;
  386.              limitcol = cols;
  387.              /* pP = pixels[row]; */
  388.              pP = pixelrow;
  389.            }
  390.            else
  391.            {
  392.             col = cols - 1;
  393.             limitcol = -1;
  394.             /* pP = &(pixels[row][col]); */
  395.             pP = &pixelrow[col];
  396.        }
  397.  
  398.            do
  399.            {
  400.              /* Use Floyd-Steinberg errors to adjust actual color. */
  401.              sr = PPM_GETR(*pP) + thisrerr[col + 1] / FS_SCALE;
  402.              sg = PPM_GETG(*pP) + thisgerr[col + 1] / FS_SCALE;
  403.              sb = PPM_GETB(*pP) + thisberr[col + 1] / FS_SCALE;
  404.              if ( sr < 0 ) sr = 0;
  405.              else if ( sr > maxval ) sr = maxval;
  406.              if ( sg < 0 ) sg = 0;
  407.              else if ( sg > maxval ) sg = maxval;
  408.              if ( sb < 0 ) sb = 0;
  409.              else if ( sb > maxval ) sb = maxval;
  410.              /* PPM_ASSIGN( *pP, sr, sg, sb ); */
  411.              PPM_ASSIGN(*pP, sr&0xF0, sg&0xF0, sb&0xF0);          
  412.              
  413.            
  414.              /* Propagate Floyd-Steinberg error terms. */
  415.              if ( fs_direction )
  416.              {
  417.                err = ( sr - (long) PPM_GETR(*pP) ) * FS_SCALE; 
  418.                thisrerr[col + 2] += ( err * 7 ) / 16;
  419.                nextrerr[col    ] += ( err * 3 ) / 16;
  420.                nextrerr[col + 1] += ( err * 5 ) / 16;
  421.                nextrerr[col + 2] += ( err     ) / 16;
  422.                err = ( sg - (long) PPM_GETG(*pP) ) * FS_SCALE;
  423.                thisgerr[col + 2] += ( err * 7 ) / 16;
  424.                nextgerr[col    ] += ( err * 3 ) / 16;
  425.                nextgerr[col + 1] += ( err * 5 ) / 16;
  426.                nextgerr[col + 2] += ( err     ) / 16;
  427.                err = ( sb - (long) PPM_GETB(*pP) ) * FS_SCALE;
  428.                thisberr[col + 2] += ( err * 7 ) / 16;
  429.                nextberr[col    ] += ( err * 3 ) / 16;
  430.                nextberr[col + 1] += ( err * 5 ) / 16;
  431.                nextberr[col + 2] += ( err     ) / 16;
  432.              }
  433.              else
  434.              {
  435.                err = ( sr - (long) PPM_GETR(*pP) ) * FS_SCALE;
  436.                thisrerr[col    ] += ( err * 7 ) / 16;
  437.                nextrerr[col + 2] += ( err * 3 ) / 16;
  438.                nextrerr[col + 1] += ( err * 5 ) / 16;
  439.                nextrerr[col    ] += ( err     ) / 16;
  440.                err = ( sg - (long) PPM_GETG(*pP) ) * FS_SCALE;
  441.                thisgerr[col    ] += ( err * 7 ) / 16;
  442.                nextgerr[col + 2] += ( err * 3 ) / 16;
  443.                nextgerr[col + 1] += ( err * 5 ) / 16;
  444.                nextgerr[col    ] += ( err     ) / 16;
  445.                err = ( sb - (long) PPM_GETB(*pP) ) * FS_SCALE;
  446.                thisberr[col    ] += ( err * 7 ) / 16;
  447.                nextberr[col + 2] += ( err * 3 ) / 16;
  448.                nextberr[col + 1] += ( err * 5 ) / 16;
  449.                nextberr[col    ] += ( err     ) / 16;
  450.              }
  451.            
  452.              if ( fs_direction )
  453.              {
  454.                ++col;
  455.                ++pP;
  456.              }
  457.              else
  458.              {
  459.                --col;
  460.                --pP;
  461.              }
  462.            } while ( col != limitcol );      
  463.          
  464.            temperr = thisrerr;
  465.            thisrerr = nextrerr;
  466.            nextrerr = temperr;
  467.            temperr = thisgerr;
  468.            thisgerr = nextgerr;
  469.            nextgerr = temperr;
  470.            temperr = thisberr;
  471.            thisberr = nextberr;
  472.            nextberr = temperr;
  473.            fs_direction = ! fs_direction;
  474.          }                  
  475.  
  476.  
  477.  
  478.  
  479. void pgm_readpgmrow(FILE* file, gray* grayrow, int cols, gray maxval, int format)
  480.     {
  481.     register int col;
  482.     register gray* gP;
  483.     bit* bitrow;
  484.     register bit* bP;
  485.  
  486.     switch ( format )
  487.     {
  488.     case PGM_FORMAT:
  489.     for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  490.         {
  491.         *gP = pbm_getint( file );
  492. #ifdef DEBUG
  493.         if ( *gP > maxval )
  494.         pm_error( "value out of bounds (%u > %u)\n", *gP, maxval );
  495. #endif /*DEBUG*/
  496.         }
  497.     break;
  498.     
  499.     case RPGM_FORMAT:
  500.     for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  501.         {
  502.         *gP = pbm_getrawbyte( file );
  503. #ifdef DEBUG
  504.         if ( *gP > maxval )
  505.         pm_error( "value out of bounds (%u > %u)\n", *gP, maxval );
  506. #endif /*DEBUG*/
  507.         }
  508.     break;
  509.     
  510.     case PBM_FORMAT:
  511.     case RPBM_FORMAT:
  512.     bitrow = pbm_allocrow( cols );
  513.     pbm_readpbmrow( file, bitrow, cols, format );
  514.     for ( col = 0, gP = grayrow, bP = bitrow; col < cols; ++col, ++gP, ++bP )
  515.         *gP = ( *bP == PBM_WHITE ) ? maxval : 0;
  516.     pbm_freerow( bitrow );
  517.     break;
  518.  
  519.     default:
  520.     pm_error( "can't happen\n" );
  521.     }
  522.     }
  523.  
  524. void pbm_readpbmrow(FILE *file, bit *bitrow, int cols, int format )
  525.     {
  526.     register int col, bitshift;
  527.     register unsigned char item;
  528.     register bit* bP;
  529.  
  530.     switch ( format )
  531.     {
  532.     case PBM_FORMAT:
  533.     for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
  534.         *bP = pbm_getbit( file );
  535.     break;
  536.  
  537.     case RPBM_FORMAT:
  538.     bitshift = -1;
  539.     for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
  540.         {
  541.         if ( bitshift == -1 )
  542.         {
  543.         item = pbm_getrawbyte( file );
  544.         bitshift = 7;
  545.         }
  546.         *bP = ( item >> bitshift ) & 1;
  547.         --bitshift;
  548.         }
  549.     break;
  550.  
  551.     default:
  552.     pm_error( "can't happen\n" );
  553.     }
  554.     }
  555.  
  556. static bit pbm_getbit(FILE *file )
  557.     {
  558.     register char ch;
  559.  
  560.     do
  561.     {
  562.     ch = pbm_getc( file );
  563.     }
  564.     while ( ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' );
  565.  
  566.     if ( ch != '0' && ch != '1' )
  567.     pm_error( "junk in file where bits should be\n" );
  568.  
  569.     return ( ch == '1' ) ? 1 : 0;
  570.     }
  571.  
  572.  
  573. pixel *next_pixrow(FILE *fp, int row, int ColorShift)
  574. {
  575.   int i;
  576.   pixel *pP;
  577.  
  578.     if( pixels )
  579.         pixrow = pixels[row];
  580.     else {
  581.         if( row != rowcnt )
  582.             pm_error("big mistake\n");
  583.         rowcnt++;
  584.         ppm_readppmrow(fp, pixrow, cols, maxval, ppmformat);
  585.         if(maxval == 255)
  586.         {
  587.           for(i=0,pP=pixrow; i<cols; i++,pP++)
  588.           {
  589.             pP->r = pP->r >> ColorShift;
  590.             pP->g = pP->g >> ColorShift;
  591.             pP->b = pP->b >> ColorShift;
  592.           }
  593.         }
  594.         else
  595.         { 
  596.           for(i=0,pP=pixrow; i<cols; i++,pP++) PPM_DEPTH(*pP, *pP, maxval, ColorRegMax);
  597.         } 
  598.     }
  599.     return pixrow;
  600. }
  601.